package ngram_reader.viewer;

import ngram_reader.viewer.query.Accumulator;
import function.unary.UnaryFunction;
import java.io.File;
import java.util.List;
import ngram.exception.InvalidConvertedFileException;
import ngram.reader.V2FileReader;
import ngram.util.CountingDataInputStream;
import ngram.util.IOUtil;
import ngram_reader.viewer.query.NGramSearchQuery;
import swingExtended.EstimatingProgressBar;
import swingExtended.progressPanel.ProgressPanel;

/**
 *
 * @author Shimu
 * @date 10-Nov-2013
 */
public class NGramSearch_V2 extends NGramSearch {

    public NGramSearch_V2(ProgressPanel panel, List<File> inputDirs,
            NGramSearchQuery query, EstimatingProgressBar progressBar) {
        super(panel, inputDirs, query, progressBar);
    }

    @Override
    protected void process(String fileUrl) throws Exception {
        try (CountingDataInputStream stream = IOUtil.getCountableInputStream(fileUrl)) {
            String n_gram;

        UnaryFunction<String, Boolean> isTarget = this.searchQuery.getIsTarget();

        Accumulator yearMatchVolumeAc = this.searchQuery.getAccumulator();

        V2FileReader reader = new V2FileReader(stream);

        while (!isCancelled() && (n_gram = reader.readNGram()) != null) {
            // The number of bytes that follows
            int bytes = reader.readHeader();

            if (isTarget.evaluate(n_gram)) {
                if (searchQuery.ignoreStatistics()) {
                    reader.skip(bytes);

                    publishText(n_gram, true);
                } else {
                    
                    final long limit = stream.getCount() + bytes;
                    long i;
                    while((i = stream.getCount()) != limit) {
                        if (i > limit) {
                            throw new InvalidConvertedFileException("Corrupt header");
                        }
                        int year = reader.readYear();
                        long match_count = reader.readMatchCount();
                        long volume_count = reader.readVolumeCount();
                        yearMatchVolumeAc.accumulate(year, match_count, volume_count);
                    }
                    
                    final String value = yearMatchVolumeAc.getAccumulatedValue();
                    yearMatchVolumeAc.reset();
                    if (!value.isEmpty()) {
                        publishText(n_gram, true);
                        publishText(value, false);
                    }
                }

            } else {
                // Skip the year, count information since the n-gram
                // is not our target
                reader.skip(bytes);
            }
        }
        }
    }
}
